导航组件概览 | MAD Skills
概览
关于导航组件,网上已经有一些不错的内容资料:
官方的入门教程:
https://developer.android.google.cn/guide/navigation/navigation-getting-started
Ian Lake 最近发布的视频:
https://v.youku.com/v_show/id_XNDc5ODgwNTExMg==.html
Android 中文教学视频: Android Jetpack 导航组件
导航组件介绍
导航模板
我们将使用这些模板之一的 Basic Activity 模板来创建一个新应用。除此之外的其他一些模板也自带导航,不过我们暂时先使用这个模板。
这个模板会帮我们创建一个包含导航组件基础结构的应用。我们还会得到两个目的地 (destination),以及定义了它们彼此之间导航路径的导航图。 | |
IDE 加载完毕该应用之后,打开导航资源文件 nav_graph.xml 并在 Design 模式 (此外还有 Code 与 Split 模式) 下查看。您会看到当前应用导航图的样子。
您会发现两个目的地: FirstFragment 是那个被设置为初始页或者叫首页的目的地。SecondFragment 是另外那个我们可以导航到的目的地。 |
导航文档 - Navigation 组件使用入门 https://developer.android.google.cn/guide/navigation/navigation-getting-started
但是,代码呢?
到目前为止,我们一直在使用图形化工具开发导航,而像 Android Studio 中所有的资源文件一样,这些都是通过 XML 代码实现的,所以您也可以直接查看和编辑这些代码。如果在工具中切换到代码 (Code) 模式,您会发现如下的 XML 代码:
<?xml version="1.0" encoding="utf-8"?>
<navigation
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/nav_graph"
app:startDestination="@id/FirstFragment">
<fragment
android:id="@+id/FirstFragment"
android:name="com.android.samples.navoverviewarticle.FirstFragment"
android:label="@string/first_fragment_label"
tools:layout="@layout/fragment_first">
<action
android:id="@+id/action_FirstFragment_to_SecondFragment"
app:destination="@id/SecondFragment" />
</fragment>
<fragment
android:id="@+id/SecondFragment"
android:name="com.android.samples.navoverviewarticle.SecondFragment"
android:label="@string/second_fragment_label"
tools:layout="@layout/fragment_second">
<action
android:id="@+id/action_SecondFragment_to_FirstFragment"
app:destination="@id/FirstFragment" />
</fragment>
</navigation>
起始目的地 (start destination) https://developer.android.google.cn/guide/navigation/navigation-getting-started#Designate-start
override fun onViewCreated(view: View, savedInstanceState: Bundle?){
super.onViewCreated(view, savedInstanceState)
view.findViewById<Button>(R.id.button_first)
.setOnClickListener {
findNavController()
.navigate(R.id.action_FirstFragment_to_SecondFragment)
}
}
运行应用并使用 Next/Previous 按钮和返回按钮来导航
导航 UI 层次结构
利用 Navigation Drawer Activity 模板创建的应用
和之前我们使用 Basic Activity 模板创建的应用不同,这个应用没有可以点击并导航到下一个目的地的按钮。取而代之的是在 DrawerLayout 中可以触发导航的菜单选项:
当用户点击 DrawerLayout 中的菜单项时,应用会导航至和那些菜单项关联的目的地。这是因为导航组件自动绑定了菜单项和对应的目的地,所以您不必手动编写代码来创建这些链接。
让我们来看一下使这一切成功运转的 UI 层次结构。为了查看它,我们需要使用 Android Studio 中的布局检查器 (Layout Inspector) 来剖析这个应用的 UI。
布局检查器 (Layout Inspector) 让我们可以以图形化的方式查看整个应用的视图层次结构,同时我们也可以看到每一个容器及视图的属性。您应该可以看到如下图所示:
图中蓝色的矩形指示着当前被选中视图 (在上图示例中,DecorView 中的顶层 LinearLayout) 的边界。
其实我们本可以查看整个应用的层次结构 (而且我也十分鼓励大家这么做,这有助于可视化标准视图层级中所发生的事),但是我只想选择几个特定的视图来解释。首先,让我们看一下 ConstraintLayout 视图:
ConstraintLayout 容器是在 main_activity.xml 布局文件中被定义的,它包含了应用的实际内容 (但并不是所有内容,比如像 ActionBar 这种被模板创建好的元素)。在该容器中,我们可以看到 NavHostFragment 元素:
NavHostFragment 是使用导航组件时产生魔力的源泉,当用户在 fragment 之间导航的时候,它是 fragment 目的地被替换进出的容器。
另一个我想特别指出的是 NavigationView:
导航部件
我们已经在层级结构中查看了几个 UI 组件,以及它们彼此之间是如何关联的,接下来我想介绍一下几个重要部件,导航组件正是利用它们来在目的地之间实现导航。
一开始使用导航组件的时候,我发现有几个地方很让人迷惑,因为很多部件都使用 Navigation 和 Nav 这样的字眼,并且有些竟然比导航组件库本身存在的还要早。所以我觉得理解这些主要的部件是什么以及它们彼此的关系应该会很有帮助。
为了图解这些部件是如何整合的,我会使用一个简化的应用容器的略图:
我们会发现 Toolbar 在顶部,其中包括了 ActionBar 菜单按钮。然后应用内容存在于下方,其中包括了 NavHostFragment,而 NavHostFragment 包括了当前目的地的 UI。
正如我前面提到的,NavHostFragment 是导航时大量操作发生的地方。它是一个被导航组件用来替换进出目的地 fragment 的容器。当您在应用中导航到一个指定的 fragment 目的地时,NavHostFragment 会将其内容替换为那个指定的 fragment。
NavController 是一个被导航组件使用的内部部件,其在幕后起着决定性的作用。当用户在应用中导航的时候,NavController 在导航组件库中掌握着处理 NavHostFragment 替换进出目的地 fragment 的逻辑。
接下来是 NavigationView,它是一个从左边划入的抽屉式导航栏。它在导航图中提供了一个可能目的地的菜单栏。NavigationView 其中一个很酷的特性是,您可以使用菜单项的 ID 自动地导航到对应菜单项关联的目的地,从而避免了手动创建基于菜单选择的重复代码。
有一点需要注意的是 NavigationView 存在于 NavHostFragment 容器之外,它本身并不是一个目的地,而只是一个指定应用导航目的地的途径。另外值得关注的一点是,早在其被导航组件整合进导航系统之前,这个 API 已经存在并被使用了很长一段时间。
NavigationUI
这个导航组件的部件被用来更新 NavHostFragment 以外的 UI。大部分的导航相关的图像更新发生在 NavHostFragment 内部,但是系统中仍然存在其他需要更新且不在容器内的部件,比如我们上面看到的抽屉式导航栏,以及类似 tab bar 的元素 (该组件可以被用来展示当前目的地信息)。
总结
这篇文章只是关于导航组件的一个快速概览,目的是为了让您体验如何创建一个可以使用导航功能的应用,以及看一下这种应用的大致结构。在未来的文章和视频中,针对如何同特定导航 API 进行交互,我会介绍更多的技术细节,比如导航到对话框目的地、使用 SafeArgs 以及处理深层链接。
更多信息
想了解更多关于导航组件的信息,请查阅 developer.android.google.cn 上的教程 Navigation 组件使用入门。
Navigation 组件使用入门 https://developer.android.google.cn/guide/navigation/navigation-getting-started
推荐阅读